﻿using System;
using System.ComponentModel;
using System.Globalization;

namespace HML
{
    /// <summary>
    ///左右内边距 
    /// </summary>
    [Serializable]
    [TypeConverterAttribute(typeof(LRPaddingConverter))]
    public struct LRPadding
    {
        #region 字段

        private bool _all;
        private int _left;
        private int _right;

        public static readonly LRPadding Empty = new LRPadding(0);

        #endregion

        #region 属性

        /// <summary>
        /// 全部
        /// </summary>
        [Description("全部")]
        [DefaultValue(0)]
        [RefreshProperties(RefreshProperties.All)]
        public int All
        {
            get
            {
                return this._all ? this._left : -1;
            }
            set
            {
                if (value < 0)
                {
                    return;
                }

                if (this._all != true || this._left != value)
                {
                    this._all = true;
                    this._left = this._right = value;
                }
            }
        }

        /// <summary>
        /// 左边内边距
        /// </summary>
        [Description("左边内边距")]
        [DefaultValue(0)]
        [RefreshProperties(RefreshProperties.All)]
        public int Left
        {
            get
            {
                if (this._all)
                {
                    return this._left;
                }
                return this._left;
            }
            set
            {
                if (value < 0)
                {
                    return;
                }

                if (this._all || this._left != value)
                {
                    this._all = false;
                    this._left = value;
                }
            }
        }

        /// <summary>
        /// 右边内边距
        /// </summary>
        [Description("右边内边距")]
        [DefaultValue(0)]
        [RefreshProperties(RefreshProperties.All)]
        public int Right
        {
            get
            {
                if (this._all)
                {
                    return this._left;
                }
                return this._right;
            }
            set
            {
                if (value < 0)
                {
                    return;
                }

                if (this._all || this._right != value)
                {
                    this._all = false;
                    this._right = value;
                }
            }
        }

        #endregion

        #region  构造

        /// <summary>
        /// 
        /// </summary>
        /// <param name="all">全部边距</param>
        public LRPadding(int all)
        {
            this._all = true;
            this._left = this._right = all;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="left">左边内边距</param>
        /// <param name="right">右边内边距</param>
        public LRPadding(int left, int right)
        {
            this._left = left;
            this._right = right;
            this._all = (this._left == this._right);
        }

        #endregion

        #region 运算符重载

        /// <summary>
        /// 判断两个边距对象设置是否一样
        /// </summary>
        /// <param name="rc1"></param>
        /// <param name="rc2"></param>
        /// <returns></returns>
        public static bool operator ==(LRPadding rc1, LRPadding rc2)
        {
            return rc1.Left == rc2.Left && rc1.Right == rc2.Right;
        }

        /// <summary>
        /// 判断两个边距对象设置是否不一样
        /// </summary>
        /// <param name="rc1"></param>
        /// <param name="rc2"></param>
        /// <returns></returns>
        public static bool operator !=(LRPadding rc1, LRPadding rc2)
        {
            return !(rc1 == rc2);
        }

        #endregion

        #region 重写

        /// <summary>
        /// 获取该对象的哈希值（参考源码）
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Left ^ RotateLeft(this.Right, 8);
        }

        /// <summary>
        /// 判断是否和该对象的引用是一样
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public override bool Equals(object other)
        {
            if (other is LRPadding)
            {
                return ((LRPadding)other) == this;
            }
            return false;
        }

        /// <summary>
        /// 把该对象转换成字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return "{Left=" + this.Left.ToString(CultureInfo.CurrentCulture) + ",Right=" + this.Right.ToString(CultureInfo.CurrentCulture) + "}";
        }

        #endregion

        #region 方法

        /// <summary>
        /// 计算哈希值（参考源码）
        /// </summary>
        /// <param name="value"></param>
        /// <param name="nBits"></param>
        /// <returns></returns>
        public static int RotateLeft(int value, int nBits)
        {
            nBits = nBits % 32;
            return value << nBits | (value >> (32 - nBits));
        }

        /// <summary>
        /// 是否应该使用All设置初始化对象
        /// </summary>
        /// <returns></returns>
        public bool ShouldSerializeAll()
        {
            return this._all;
        }

        #endregion
    }

}
